﻿
#include "base/SimpleThread.h"

#include <sys/types.h> 
#include <sys/timeb.h>
#include <assert.h>
#include <signal.h>

namespace base
{

#if defined(WIN32)
    static DWORD WINAPI ThreadFunc(void* params)
    {
        SimpleThread* thread = static_cast<SimpleThread*>(params);
        thread->ThreadMain();
        return NULL;
    }
#else

    static void* OS_Thread_Proc_Linux(void* params)
    {
        SimpleThread* thread = static_cast<SimpleThread*>(params);

#if defined(ANDROID) || defined(LINUX)
		prctl(PR_SET_NAME, (unsigned long)"sr-simplethread"); 
#endif

        thread->ThreadMain();
        return NULL;
    }

#endif

    SimpleThread::SimpleThread()
        : m_Priv(NULL),
          is_stop_(true)
    {
    }

    SimpleThread::~SimpleThread()
    {
        if(m_Priv)
        {
            OS_Thread_Priv* priv = (OS_Thread_Priv*)m_Priv;
            delete priv;
        }
    }

    int SimpleThread::Start()
    {
        if(m_Priv)
        {
            printf("%s %d\n", __FUNCTION__, __LINE__);
            assert(false);
        }

        // 创建私有结构
        OS_Thread_Priv* priv = new OS_Thread_Priv;

        if(!priv) return -1;

        m_Priv = priv;
#if defined(WIN32)
        priv->hThread = ::CreateThread(NULL, 0, ThreadFunc, this, 0, NULL);
#else

        // 创建线程

		sigset_t signal_mask;
		sigemptyset(&signal_mask);
		sigaddset(&signal_mask, SIGPIPE);
		int rc = pthread_sigmask(SIG_BLOCK, &signal_mask, NULL);
		if (rc != 0) {
			//LogERR("block sigpipe error\n");
	}
		pthread_attr_t attr;
		pthread_attr_init(&attr);
		pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
		pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

        if(pthread_create(&priv->hThread, NULL, OS_Thread_Proc_Linux, this) < 0)
        {
            delete priv;
            m_Priv = NULL;
            return -1;
        }

#endif

        if(priv->hThread == NULL)
        {
            delete priv;
            m_Priv = NULL;
            return -1;
        }

        return 0;
    }

    int SimpleThread::Stop()
    {
        is_stop_ = true;
        return 0;
    }

    bool SimpleThread::IsStop()
    {
        return is_stop_;
    }

    void SimpleThread::Join()
    {
        OS_Thread_Priv* priv = (OS_Thread_Priv*)this->m_Priv;

        if(priv)
        {
#if  defined(WIN32)
            ::WaitForSingleObject(priv->hThread, INFINITE);
            ::CloseHandle(priv->hThread);
#else
            pthread_join(priv->hThread, NULL);
#endif
            delete priv;
            this->m_Priv = NULL;
        }
    }

    void SimpleThread::ThreadMain()
    {
        is_stop_ = false;
        Run();
    }

} // namespace base
